<?php

declare(strict_types=1);

namespace App\CustHub\Service;

use App\Common\Constants\GenderConstants;
use App\CustHub\Amqp\Producers\CommonProducers;
use App\CustHub\Amqp\Producers\SendRecordProducers;
use App\CustHub\Constants\ContactSourceConstants;
use App\CustHub\Constants\MsgTypeConstants;
use App\CustHub\Constants\OpSchemeTypeConstants;
use App\CustHub\Constants\SendConfigConstants;
use App\CustHub\Constants\SendRecordStatusConstants;
use App\CustHub\Constants\SmartPushSchemeStatusConstants;
use App\CustHub\Constants\SmartPushSchemeSubStatusConstants;
use App\CustHub\Constants\SmartPushSchemeTaskStatusConstants;
use App\CustHub\Constants\SmartPushSchemeTypeConstants;
use App\CustHub\Dto\CommonProducersDto;
use App\CustHub\Dto\SendRecordProducersDto;
use App\CustHub\Helpers\BcMath;
use App\CustHub\Helpers\TagReplacer;
use App\CustHub\Mapper\ChRobotMapper;
use App\CustHub\Mapper\ChSendRecordMapper;
use App\CustHub\Mapper\ChSmartPushSchemeMapper;
use App\CustHub\Mapper\ChSmartPushSchemeSubTaskMapper;
use App\CustHub\Model\ChContact;
use App\CustHub\Model\ChCorpTag;
use App\CustHub\Model\ChSendRecord;
use App\CustHub\Model\ChSmartPushScheme;
use App\CustHub\Model\ChSmartPushSchemeRobot;
use App\CustHub\Model\ChSmartPushSchemeStatistic;
use App\CustHub\Model\ChSmartPushSchemeSubTask;
use App\CustHub\Model\ChSmartPushSchemeTask;
use App\CustHub\Model\ChSmartTag;
use Carbon\Carbon;
use Hyperf\Amqp\Producer;
use Hyperf\Di\Annotation\Inject;
use Mine\Abstracts\AbstractService;
use Mine\Annotation\Transaction;
use Mine\Exception\NormalStatusException;
use Mine\MineModel;
use function Hyperf\Collection\data_get;

/**
 * 智能推送方案服务类
 */
class ChSmartPushSchemeService extends AbstractService
{
    public $mapper;

    #[Inject]
    protected ChSendRecordMapper $sendRecordMapper;

    #[Inject]
    protected ChSmartPushSchemeSubTaskMapper $schemeSubMapper;

    #[Inject]
    protected ChRobotMapper $robotMapper;

    #[Inject]
    protected ChSmartPushSchemeStatisticsService $schemeStatisticsService;

    public function __construct(ChSmartPushSchemeMapper $mapper)
    {
        $this->mapper = $mapper;
    }

    public function getSchemeList(array $params)
    {
        $data = $this->mapper->getSchemeList($params);
        $list = $data['items'];

        foreach ($list as $k => $item) {
            $list[$k]['status_text'] = SmartPushSchemeStatusConstants::getMessage($item['status']);
            $list[$k]['push_type_text'] = SmartPushSchemeTypeConstants::getMessage($item['push_type']);
            $comp_rate = 0;
            if($item['reach_count'] > 0){
                $comp_rate = BcMath::mul($item['completed_count']/$item['reach_count'],100);
            }
            $list[$k]['comp_rate'] = $comp_rate;
        }
        $data['items'] = $list;
        return $data;
    }

    /**
     * 新增数据
     * @param array $data
     * @return mixed
     */
    #[Transaction]
    public function save(array $data): mixed
    {
        $pushType = $data['push_type'];
        $robotIds = json_decode($data['robot_ids']);
        $jsonField = ['aud_cfg','content','cycle_cfg','push_tgt_cfg'];
        foreach ($jsonField as $field){
            if(isset($data[$field])){
                $data[$field] = json_decode($data[$field],true);
            }
        }
        $cycleCfg = $data['cycle_cfg'];
        $endTime = null;
        $status = SmartPushSchemeStatusConstants::SENDING;
        if ($pushType == SmartPushSchemeTypeConstants::TIMING_SINGLE) {
            $beginTime = $cycleCfg['push_time'];
            $status = SmartPushSchemeStatusConstants::CREATING;
        } elseif ($pushType == SmartPushSchemeTypeConstants::TIMING_REPEAT) {
            $unit = (int)$cycleCfg['unit'];
            if($unit == 0){
                $val = [];
            }else{
                $val = $cycleCfg['val'];
            }
            $beginTime = get_next_send_time($cycleCfg['push_time'],(int)$cycleCfg['unit'],$val);
            $endTime = empty($cycleCfg['end_time']) ? null : $cycleCfg['end_time'];
        }else{
            $beginTime = $cycleCfg['start_time'];
            $endTime = $cycleCfg['end_time'];
        }
        $data['begin_time'] = $beginTime;
        $data['end_time'] = $endTime;
        $data['status'] = $status;
        $data['created_at'] = $data['updated_at'] = Carbon::now()->toDateTimeString();
        $this->mapper->filterExecuteAttributes($data, $this->mapper->getModel()->incrementing);
        /** @var ChSmartPushScheme $scheme */
        $scheme = $this->mapper->model::create($data);
        if($scheme){
            $scheme->robots()->sync($robotIds,false);
            // 创建子任务且不为触发型的情况
            if($pushType == SmartPushSchemeTypeConstants::TIMING_SINGLE){
                container()->get(Producer::class)->produce(new CommonProducers(new CommonProducersDto(classname: ChSmartPushSchemeSubService::class, method: 'createTask', data: ['scheme_id' => $scheme->id])));
            }
        }
        return $scheme->id;
    }

    /**
     * 更新
     * @param array $data
     * @return bool
     */
    #[Transaction]
    public function updateScheme(array $data): bool
    {
        $info = $this->mapper->findById($data['id']);
        if(empty($info)){
            throw new NormalStatusException('请求失败');
        }
        $pushType = $data['push_type'];
        $cycleCfg = json_decode($data['cycle_cfg'], true);
        if ($pushType == SmartPushSchemeTypeConstants::TIMING_SINGLE) {
            $beginTime = $cycleCfg['push_time'];
        } elseif ($pushType == SmartPushSchemeTypeConstants::TIMING_REPEAT) {
            $beginTime = get_next_send_time($cycleCfg['push_time'],(int)$cycleCfg['unit'],$cycleCfg['val']);
        }else{
            $beginTime = $cycleCfg['start_time'];
        }
        $data['begin_time'] = $beginTime;

        $jsonField = ['aud_cfg','content','cycle_cfg','push_tgt_cfg'];
        foreach ($jsonField as $field){
            if(isset($data[$field])){
                $data[$field] = json_decode($data[$field],true);
            }
        }

        $rst= $this->mapper->update($data['id'],$data);
        if($rst){
            $info->robots()->sync(json_decode($data['robot_ids']));
            $this->mapper->delCache($data['id']);
        }
        return $rst;
    }

    public function getInfo(array $data)
    {
        $info = $this->mapper->model::query()
            ->with(['robots'=>function ($query) {
                $query->select(['id','nickname','avatar','corp_name']);
            },'corp'=>function ($query) {
                $query->select(['id','corp_name']);
            }])
            ->where('main_uid',$data['main_uid'])
            ->where('id',$data['id'])
            ->first();
        if(empty($info)){
            throw new NormalStatusException('信息异常');
        }
        $robotIds = $info->robots()->pluck('id')->toArray();
        $info = $info->toArray();
        $info['robot_ids'] = $robotIds;
        $info['push_type_text'] = SmartPushSchemeTypeConstants::getMessage($info['push_type']);
        $info['status_text'] = SmartPushSchemeStatusConstants::getMessage($info['status']);
        //受众配置
        $audCfg = $info['aud_cfg'];
        $audCfgItems = $audCfg['items'];
        foreach ($audCfgItems as $k=>$cfgList){
            foreach ($cfgList['items'] as $ck=>$item){
                $value = $item['value'];
                $event = $item['event'];
                $text = $this->getText($value,$event);
                !empty($text) && $audCfgItems[$k]['items'][$ck]['text'] = $text;
            }
        }
        $info['aud_cfg']['items'] = $audCfgItems;
        //推送配置
        if($info['push_type'] == SmartPushSchemeTypeConstants::TRIGGER_COMPLETE){
            $cfg = $info['cycle_cfg']['cfg'];
            $cycleCfgItems = $cfg['items'];
            foreach ($cycleCfgItems as $k=>$cfgList){
                foreach ($cfgList['items'] as $ck=>$item){
                    $value = $item['value'];
                    $event = $item['event'];
                    $text = $this->getText($value,$event);
                    !empty($text) && $cycleCfgItems[$k]['items'][$ck]['text'] = $text;
                }
            }
            $info['cycle_cfg']['cfg']['items'] = $cycleCfgItems;
        }

        //目标配置
        if(!empty($info['push_tgt_cfg'])){
            $tgtCfg = $info['push_tgt_cfg']['cfg'];
            $tgtCfgItems = $tgtCfg['items'];
            foreach ($tgtCfgItems as $k=>$cfgList){
                foreach ($cfgList['items'] as $ck=>$item){
                    $value = $item['value'];
                    $event = $item['event'];
                    $text = $this->getText($value,$event);
                    !empty($text) && $tgtCfgItems[$k]['items'][$ck]['text'] = $text;
                }
            }
            $info['push_tgt_cfg']['cfg']['items'] = $tgtCfgItems;
            $info['push_tgt_cfg']['corp_tag_text'] = ChCorpTag::query()->whereIn('id',$info['push_tgt_cfg']['corp_tag_ids'])->pluck('name')->toArray();
            $info['push_tgt_cfg']['smart_tag_text'] = ChSmartTag::query()->whereIn('id',$info['push_tgt_cfg']['smart_tag_ids'])->pluck('name')->toArray();
        }

        $completedCnt = $info['completed_count'];
        $reachCount = $info['reach_count'];
        if($reachCount == 0){
            $completedRate = 0;
        }else{
            $completedRate = round($completedCnt/$reachCount,2);
        }

        $info['completed_rate'] = $completedRate;

        return $info;
    }

    private function getText($event,$value)
    {
        $text = [];
        if($event == 'corp_tag'){
            $text = ChCorpTag::query()->whereIn('id',$value)->pluck('name')->toArray();
        }elseif ($event == 'smart_tag'){
            $text = ChSmartTag::query()->whereIn('id',$value)->pluck('name')->toArray();
        }elseif ($event == 'gender'){
            foreach ($value as $gender){
                $text[] = GenderConstants::getMessage($gender);
            }
        }elseif ($event == 'source'){
            foreach ($value as $gender){
                $text[] = ContactSourceConstants::getMessage($gender);
            }
        }
        return $text;
    }

    /**
     * 暂停任务
     * @param array $params
     * @return bool
     */
    public function pauseTask(array $params): bool
    {
        $info = $this->mapper->findById($params['id']);

        if(empty($info)){
            throw new NormalStatusException('请选择任务');
        }

        if($info->status != SmartPushSchemeStatusConstants::SENDING){
            throw new NormalStatusException('当前状态不允许操作');
        }
        //暂停任务
        $info->status = SmartPushSchemeStatusConstants::PAUSED;
        $rst = $info->save();
        if(!$rst){
            return false;
        }
        $this->mapper->delCache($info->id);
        return true;
    }

    /**
     * 开启任务
     * @param array $params
     * @return bool
     */
    public function startTask(array $params): bool
    {
        $info = $this->mapper->findById($params['id']);

        if(empty($info)){
            throw new NormalStatusException('请选择任务');
        }

        if($info->status != SmartPushSchemeStatusConstants::PAUSED){
            throw new NormalStatusException('当前状态不允许操作');
        }

        //开启任务
        $info->status = SmartPushSchemeStatusConstants::SENDING;
        $rst = $info->save();
        if(!$rst){
            return false;
        }
        $this->mapper->delCache($info->id);
        return true;
    }

    /**
     * 取消任务
     * @param array $params
     * @return true
     */
    #[Transaction]
    public function cancelTask(array $params): bool
    {
        $info = $this->mapper->findById($params['id']);

        if(empty($info)){
            throw new NormalStatusException('请选择任务');
        }

        if($info->status == SmartPushSchemeStatusConstants::COMPLETED){
            throw new NormalStatusException('当前状态不允许操作');
        }

        $info->status = SmartPushSchemeStatusConstants::CANCELED;
        $rst = $info->save();
        if(!$rst){
            throw new NormalStatusException('操作失败，请重试');
        }

        //取消所有未完成状态下的子方案
        $subSchemeList = ChSmartPushSchemeSubTask::query()
            ->where('scheme_id',$info->id)
            ->where('status','<>',SmartPushSchemeSubStatusConstants::COMPLETED)
            ->get();

        foreach ($subSchemeList as $subScheme){
            $subScheme->status = SmartPushSchemeSubStatusConstants::CANCELED;
            $rst = $subScheme->save();
            if(!$rst){
                throw new NormalStatusException('操作失败，请重试');
            }

            //变更所有发对象的状态
            ChSendRecord::query()
                ->where('task_id',$subScheme->id)
                ->where('type',SendConfigConstants::SMART_PUSH)
                ->whereNotIn('status',[SendRecordStatusConstants::SUCCESS,SendRecordStatusConstants::FAILURE])
                ->update([
                    'status' => SendRecordStatusConstants::CANCEL
                ]);
        }
        return true;
    }

    /**
     * 暂停子任务
     * @param array $params
     * @return bool
     */
    public function pauseSubTask(array $params): bool
    {
        $info = ChSmartPushSchemeSubTask::query()
            ->where('id',$params['sub_scheme_id'])
            ->first();
        if(empty($info)){
            throw new NormalStatusException('请选择任务');
        }

        if($info->status == SmartPushSchemeSubStatusConstants::SENDING){
            throw new NormalStatusException('当前状态不允许操作');
        }

        $info->status = SmartPushSchemeSubStatusConstants::PAUSED;
        return $info->save();
    }

    /**
     * 开启任务
     * @param array $params
     * @return bool
     */
    public function startSubTask(array $params): bool
    {
        $info = ChSmartPushSchemeSubTask::query()
            ->where('id',$params['sub_scheme_id'])
            ->first();
        if(empty($info)){
            throw new NormalStatusException('请选择任务');
        }

        if($info->status != SmartPushSchemeSubStatusConstants::PAUSED){
            throw new NormalStatusException('当前状态不允许操作');
        }

        $robotInfo = $this->robotMapper->findById($info->robot_id);
        if($robotInfo->login_status == 1){
            //机器人在线的情况下 才会变更状态
            $info->status = SmartPushSchemeSubStatusConstants::SENDING;
            return $info->save();
        }else{
            return true;
        }
    }

    /**
     * 取消子任务
     * @param array $params
     * @return bool
     */
    public function cancelSubTask(array $params): bool
    {
        $info = ChSmartPushSchemeSubTask::query()
            ->where('id',$params['sub_scheme_id'])
            ->first();
        if(empty($info)){
            throw new NormalStatusException('请选择任务');
        }

        if($info->status != SmartPushSchemeSubStatusConstants::COMPLETED){
            throw new NormalStatusException('当前状态不允许操作');
        }

        $rst = $info->status = SmartPushSchemeSubStatusConstants::CANCELED;

        if(!$rst){
            throw new NormalStatusException('操作失败，请重试');
        }

        ChSendRecord::query()
            ->where('task_id',$info->id)
            ->where('type',SendConfigConstants::SMART_PUSH)
            ->whereNotIn('status',[SendRecordStatusConstants::SUCCESS,SendRecordStatusConstants::FAILURE])
            ->update([
                'status' => SendRecordStatusConstants::CANCEL
            ]);

        //查询主任务是否存在尚未完成的子任务
        $unfinishedStatus = [
            SmartPushSchemeSubStatusConstants::WAITING,
            SmartPushSchemeSubStatusConstants::SENDING,
            SmartPushSchemeSubStatusConstants::PAUSED
        ];
        $exists =  ChSmartPushSchemeSubTask::query()
            ->where('scheme_id',$info->scheme_id)
            ->whereIn('status',$unfinishedStatus)
            ->exists();
        if(!$exists){
            //不存在子任务的情况下 取消主任务
            $mainScheme = $this->mapper->findById($info->scheme_id);
            if($mainScheme->push_type == SmartPushSchemeTypeConstants::TIMING_SINGLE || ($mainScheme->push_type == SmartPushSchemeTypeConstants::TIMING_REPEAT && $mainScheme->end_time > time())){
                $mainScheme->status = SmartPushSchemeStatusConstants::CANCELED;
                $rst = $mainScheme->save();
                if(!$rst){
                    throw new NormalStatusException('操作失败，请重试');
                }
                $this->mapper->delCache($mainScheme->id);
            }
        }
        return true;
    }

    /**
     * 获取主任务
     * @param array $params
     * @return array
     */
    public function getTaskList(array $params): array
    {
        $schemeId = $params['id'];
        $pageSize = $params['page_size'] ?? MineModel::PAGE_SIZE;
        $p = ChSmartPushSchemeTask::query()
            ->select(['id','scheme_id','send_time','contact_cnt','content','status'])
            ->with(['scheme'=>function ($query) {
                $query->select(['id','title']);
            }])
            ->where('scheme_id',$schemeId)
            ->orderBy('send_time','desc')
            ->paginate((int)$pageSize);

        $p->getCollection()->transform(function ($item){
           $item->send_time_text = datetime(strtotime($item->send_time),'m-d H:i').' 开始';
           $item->status_text = SmartPushSchemeTaskStatusConstants::getMessage($item->status);
           return $item;
        });

        return $this->mapper->setPaginate($p);
    }

    /**
     * 获取子任务列表
     * @param array $params
     * @return array
     */
    public function getSubTaskList(array $params): array
    {
        $taskId = data_get($params,'task_id');
        $pageSize = $params['page_size'] ?? MineModel::PAGE_SIZE;
        //定时-单次
        $list = ChSmartPushSchemeSubTask::query()
            ->select(['id','robot_id','status','contact_count','completed_count'])
            ->with(['robot'=>function ($query) {
                $query->select(['id','nickname','avatar','corp_name','login_status']);
            }])
            ->where('scheme_id',$params['id'])
            ->when(!empty($taskId),function ($query) use ($taskId){
                $query->where('task_id',$taskId);
            })
            ->orderBy('id','desc')
            ->paginate((int)$pageSize);

        $list->getCollection()->transform(function ($item){
            $item->status_text = SmartPushSchemeSubStatusConstants::getMessage($item->status);
            return $item;
        });

        return $this->mapper->setPaginate($list);
    }

    /**
     * 获取目标用户列表
     * @param array $params
     * @return array
     */
    public function getTargetList(array $params): array
    {
        $schemeId = $params['id'];
        $params['task_id'] = $schemeId;
        $params['sub_task_id'] = $params['sub_scheme_id'] ?? '';
        $fields = ['id','robot_id','to_id','status','start_time'];
        $params['type'] = SendConfigConstants::SMART_PUSH;
        return $this->sendRecordMapper->getRecordPageList($params,$fields);
    }

    /**
     * 取消目标用户
     * @param array $params
     * @return bool
     * @throws \Psr\Container\ContainerExceptionInterface
     * @throws \Psr\Container\NotFoundExceptionInterface
     * @throws \RedisException
     */
    #[Transaction]
    public function cancelTarget(array $params): bool
    {
        $subSchemeInfo = $this->schemeSubMapper->findById($params['sub_scheme_id']);

        if(empty($subSchemeInfo)){
            throw new NormalStatusException('请选择任务');
        }

        $recordInfo = $this->sendRecordMapper->model::query()
            ->where('id',$params['target_id'])
            ->where('sub_task_id',$subSchemeInfo->id)
            ->first();
        if(empty($recordInfo)){
            throw new NormalStatusException('取消失败，请重试');
        }

        $recordInfo->status = SendRecordStatusConstants::CANCEL;
        $rst = $recordInfo->save();
        if(!$rst){
            throw new NormalStatusException('取消失败，请重试');
        }

        $recordList = $this->sendRecordMapper->model::query()
            ->select(['id','status'])
            ->where('sub_task_id',$params['sub_scheme_id'])
            ->where('type',SendConfigConstants::SMART_PUSH)
            ->get();

        $totalCount = $recordList->count();

        $cancelCount = $recordList->filter(function ($item){
            return $item->status == SendRecordStatusConstants::CANCEL;
        })->count();

        $processedCount = $recordList->filter(function ($item){
            return $item->status != SendRecordStatusConstants::WAITING;
        })->count();

        $completedCount = $subSchemeInfo->completed_count + 1;
        $updateData = [
            'completed_count'=>$completedCount,
        ];
        if($totalCount == $cancelCount){
            $updateData['status'] = SmartPushSchemeSubStatusConstants::CANCELED;
            //查询主任务是否存在尚未完成的子任务
            $unfinishedStatus = [
                SmartPushSchemeSubStatusConstants::WAITING,
                SmartPushSchemeSubStatusConstants::SENDING,
                SmartPushSchemeSubStatusConstants::PAUSED
            ];
            $exists =  ChSmartPushSchemeSubTask::query()
                ->where('scheme_id',$subSchemeInfo->scheme_id)
                ->whereIn('status',$unfinishedStatus)
                ->exists();
            if(!$exists){
                //不存在子任务的情况下 取消主任务
                $mainScheme = $this->mapper->findById($subSchemeInfo->scheme_id);
                if($mainScheme->push_type == SmartPushSchemeTypeConstants::TIMING_SINGLE || ($mainScheme->push_type == SmartPushSchemeTypeConstants::TIMING_REPEAT && $mainScheme->end_time > time())){
                    $mainScheme->status = SmartPushSchemeStatusConstants::CANCELED;
                    $rst = $mainScheme->save();
                    if(!$rst){
                        throw new NormalStatusException('操作失败，请重试');
                    }
                    $this->mapper->delCache($mainScheme->id);
                }
            }

        }elseif ($totalCount == $processedCount){
            $updateData['status'] = SmartPushSchemeSubStatusConstants::COMPLETED;
        }

        //所有目标用户都取消
        ChSmartPushSchemeSubTask::query()
            ->where('id',$subSchemeInfo->id)
            ->update($updateData);
        return true;
    }

    /**
     * 获取发送记录
     * @param array $params
     * @return array
     */
    public function getSendRecord(array $params): array
    {
        $params['task_id'] = $params['id'];
        $fields = ['id','robot_id','to_id','status','start_time'];
        $params['type'] = SendConfigConstants::SMART_PUSH;
//        $params['status'] = ['op','status'=>SendRecordStatusConstants::WAITING];
        return $this->sendRecordMapper->getRecordPageList($params,$fields);
    }


    /**
     * 定时发送任务
     * @return void
     */
    public function timedMessageHandler(): void
    {
        $now = Carbon::now()->toDateTimeString();
        $list = $this->mapper->model::query()
            ->select(['id','uid','main_uid'])
            ->with(['subTask' => function ($query) {
                $query->select(['id','scheme_id','robot_id','contact_count'])->where('status', SmartPushSchemeSubStatusConstants::WAITING);
            }])
            ->whereIn('status',[SmartPushSchemeStatusConstants::WAITING,SmartPushSchemeStatusConstants::SENDING])
            ->where('begin_time','<=',$now)
            ->where('push_type',SmartPushSchemeTypeConstants::TIMING_SINGLE)
            ->where('is_running',0)
            ->get();

        $sendRecordService = container()->get(ChSendRecordService::class);
        foreach ($list as $item){
            //子任务
            $subTask = $item->subTask;
            //任务发送中
            $this->mapper->model::query()
                ->where('id',$item->id)
                ->update(['is_running' => 1]);
            $subTaskCount = count($subTask);

            foreach ($subTask as $k=>$subItem){

                $this->schemeSubMapper->model::query()
                    ->where('id',$subItem['id'])
                    ->update(['status'=>SmartPushSchemeSubStatusConstants::SENDING]);

                //是否最后一个子任务
                $isLastSubTask = false;
                if($k + 1 == $subTaskCount){
                    $isLastSubTask = true;
                }

                $sendRecordService->sendByTaskId($subItem['robot_id'],$item->id,$subItem['id'],$item->main_uid,$item->uid,SendConfigConstants::SMART_PUSH,$isLastSubTask);
            }

            //没有子任务需要发送的情况
            if($subTaskCount == 0){
                $update['is_running'] = 0;
                $update['status'] = SmartPushSchemeStatusConstants::COMPLETED;
                $this->mapper->model::query()
                    ->where('id',$item['id'])
                    ->update($update);
            }
        }

    }

    /**
     * 执行推送操作
     *
     *
     */
    private function executePush()
    {
        // 这里是发送推送的逻辑
        // 比如发送消息给企微用户等
//        $this->logger->info('执行推送', ['task_id' => $task->id, 'title' => $task->title]);
    }

    /**
     * 获取符合智能推送条件的任务
     * @param array $robotIds
     * @param array $contactIds
     * @return void
     * @throws \Psr\Container\ContainerExceptionInterface
     * @throws \Psr\Container\NotFoundExceptionInterface
     */
    public function getMeetTheConditionScheme(array $robotIds,array $contactIds): void
    {
        $robotSchemeList = ChSmartPushSchemeRobot::query()
            ->with(['scheme'])
            ->whereIn('robot_id',$robotIds)
            ->whereHas('scheme',function ($query){
                $query->where('status',SmartPushSchemeStatusConstants::SENDING)->where('push_type',SmartPushSchemeTypeConstants::TRIGGER_COMPLETE);
            })
            ->get();
        if($robotSchemeList->isEmpty()){
            return;
        }

        foreach ($robotSchemeList as $info){
            $scheme = $info->scheme;
            $aud_cfg = $scheme->aud_cfg;

            $triggerType = $scheme->cycle_cfg['trigger_type'] ?? 0;
            $isSendUserIds = [];
            if(!$triggerType){
                //不允许重复发送的情况
                $isSendUserIds = $this->sendRecordMapper->getUserIdsByTaskId($scheme->id,SendConfigConstants::SMART_PUSH);
                if(!empty($isSendUserIds)){
                    $isSendUserIds = array_unique($isSendUserIds);
                    $isSendUserIds = ChContact::query()
                        ->where('robot_id',$info->robot_id)
                        ->whereIn('user_id',$isSendUserIds)
                        ->pluck('id')
                        ->toArray();
                }
            }

            $contactIds = array_diff($contactIds,$isSendUserIds);
            if(empty($contactIds)){
                continue;
            }

            // 筛选出符合条件的用户
            $filteredContactList = $this->getFilteredContactList($contactIds,$aud_cfg);
            if($filteredContactList->isEmpty()){
                continue;
            }
            $cycle_cfg = $scheme->cycle_cfg;
            //完成条件的用户
            $qualifiedUsers = $this->getFilteredContactList($filteredContactList->pluck('id')->toArray(),$cycle_cfg['cfg']);
            if($qualifiedUsers->isEmpty()){
                continue;
            }

            //更新客户数量
            $contactCnt = $qualifiedUsers->count();
            ChSmartPushScheme::query()->where('id',$scheme->id)->increment('contact_count',$contactCnt);

            $recordData = [];
            foreach ($qualifiedUsers as $item){
                $content = $scheme['content'];
                foreach ($content as $ck=>$contentItem){
                    if($contentItem['msg_type'] == MsgTypeConstants::TEXT){
                       $content[$ck]['content'] = TagReplacer::replaceTags($contentItem['content'],[
                            'call_name_nickname' => !empty($item->call_name) ? $item->call_name : $item->nickname,
                        ]);
                    }
                }
                $recordData[] = [
                    'uid' => $scheme->uid,
                    'main_uid' => $scheme->main_uid,
                    'task_id' => $scheme->id,
                    'robot_id' => $item->robot_id,
                    'to_id' => $item->user_id,
                    'trigger_time' => time(),
                    'content' => $content,
                    'msg_total_count' => count($scheme['content']),
                    'type' => SendConfigConstants::SMART_PUSH,
                    'status' => SendRecordStatusConstants::WAITING
                ];
            }

            stdout_log()->info('发送记录'.json_encode($recordData));

            container()->get(Producer::class)->produce(new SendRecordProducers(
                (new SendRecordProducersDto())
                    ->setMainUid($scheme->main_uid)
                    ->setUid($scheme->uid)
                    ->setTaskId($scheme->id)
                    ->setType(SendConfigConstants::SMART_PUSH)
                    ->setRecordData($recordData)
                    ->setIsSendNow(true)
            ));
        }
    }

    private function getFilteredContactList(array $contactIds,array $audCfg): \Hyperf\Database\Model\Collection|array
    {
        $query = ChContact::query()->select(['id','nickname','call_name','robot_id','user_id']);
        $query->whereIn('id',$contactIds);

        $op = $audCfg['cond'] == 'or' ? 'orWhere' : "where";

        $items = $audCfg['items'];
        $schemeSubService = container()->get(ChSmartPushSchemeSubService::class);
        $query->where(function ($query) use ($op,$items,$schemeSubService){
            foreach ($items as $item){
                $query->{$op}(function ($query) use ($item,$schemeSubService){
                    $op = $item['op']  == 'or' ? 'orWhere' : "where";
                    $items = $item['items'];
                    foreach ($items as $value){
                        $query->{$op}(function ($query) use ($value,$schemeSubService){
                            $schemeSubService->getFilter($query,$value);
                        });
                    }
                });
            }
        });

        $result = $query->get();
        return $result;
    }

    /**
     * 获取统计列表
     * @param array $params
     * @return array
     */
    public function getStatsList(array $params): array
    {
        return $this->schemeStatisticsService->getStatsList($params);
    }

    /**
     * @param array $params
     * @return array
     */
    public function getDetailedDataList(array $params): array
    {
        return $this->schemeStatisticsService->getDetailedDataList($params);
    }

    /**
     * 删除方案
     * @param array $params
     * @return bool
     * @throws \Exception
     */
    #[Transaction]
    public function deleteScheme(array $params): bool
    {
        $scheme = $this->mapper->findById($params['id']);
        if($scheme){
            $scheme->robots()->detach();
            $scheme->subTask()->delete();

            ChSmartPushSchemeTask::query()->where('scheme_id',$scheme->id)->delete();
            ChSmartPushSchemeStatistic::query()->where('scheme_id',$scheme->id)->delete();
            $scheme->delete();
        }
        return true;
    }
}